#include "ngalois.h"
#include <math.h>
#include <stdio.h>

ngalois::ngalois(unsigned generador){
    grado = static_cast<int>(log2(generador));
    carrymask = static_cast<int>(pow(2,grado)); //sirve para inicializar matrices y como carrymask
    cantidad = carrymask-1;
    generarTabla(generador);
}

unsigned ngalois::mult(unsigned op1, unsigned op2){
    if(op1==0 || op2==0) return 0;
    unsigned sumalogs=this->log[op1]+this->log[op2];
    if(sumalogs>cantidad-1)
        sumalogs-=cantidad;
    return this->antilog[sumalogs];
}

void ngalois::generarTabla(unsigned generador){
    this->antilog=new unsigned[cantidad];
    this->log=new unsigned[cantidad];

    this->antilog[0]=0;
    this->log[0]=0;

    /*
    this->antilog[1]=2;
    this->log[2]=1;

    */
    int x=2;
    for (int i=1; i<this->grado; i++){

       this->antilog[i]=x;
       this->log[x]=i;
       x=x<<1;
    }
    for(int i=grado;i<cantidad;i++) {
        printf("i=%d", i);
        imprbin(x);

        if(x & carrymask){ // si se pasa del grado del polinomio
            printf("en el punto %d", i);
            imprbin(x);
            printf("+");
            imprbin(generador);
            x=x ^ generador; // suma de bits con un xor
            imprbin(x);
        }
        this->antilog[i]=x;
        this->log[x]=i;
        x=x<<1;
    }


    for(int i=0;i<=cantidad;i++)
    {
        printf("%d:", i );
        imprbin(this->log[i]);
    }
}

void ngalois::imprbin(unsigned numero){
    int bits=sizeof(int)*8;
    for (int i=0;i<bits;++i)
    if (((numero>>(bits-i-1))&1)==1) printf("1"); else printf("0");
    printf("\n");
}
